using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Scripting;
using Voodoo.Sauce.Common.Utils;
using Voodoo.Sauce.Core;
using Voodoo.Sauce.Internal;
using Voodoo.Sauce.Internal.Utils;

namespace Voodoo.Sauce.CrashReport
{
	[Preserve]
	internal class CrashReportManager : CrashReportCore
	{
		private const string TAG = "CrashReportManager";

		private const string PLAYER_PREF_CRASH_REPORTER_V1 = "PLAYER_PREF_CRASHLYTICSVoodoo.Sauce.CrashReport.CrashReporter";

		private const string PLAYER_PREF_CRASH_REPORTER_V2 = "PLAYER_PREF_CRASHLYTICSVoodoo.Sauce.CrashReport.CrashReporter.v2";

		private VoodooSettings _voodooSettings;

		private ICrashlyticsProvider _crashReporter;

		private readonly Dictionary<CrashReporter, float> _crashReporterPercentages = new Dictionary<CrashReporter, float>();

		public override void Initialize(CrashReportManagerParameters parameters)
		{
			RemoveOutdatedSavedConfigurations();
			_voodooSettings = parameters.VoodooSettings;
			_crashReporter = SelectCrashReporter();
			_crashReporter?.Initialize(ref parameters.AnalyticsConsentEvent);
		}

		public override CrashReporter GetCrashReporter()
		{
			return _crashReporter?.CrashReporterType() ?? CrashReporter.None;
		}

		internal override void ForceCrashReporter(CrashReporter crashReporter)
		{
			NintendoPlayerPrefs.SetString("PLAYER_PREF_CRASHLYTICSVoodoo.Sauce.CrashReport.CrashReporter.v2", crashReporter.ToString());
			VoodooLog.LogDebug(Module.ANALYTICS, "CrashReportManager", "Crash reporter forced to: '" + crashReporter.ToString() + "'");
		}

		public override void LogLevelStart(string level)
		{
			_crashReporter?.LogLevelStart(level);
		}

		public override void LogLevelFinish(string level)
		{
			_crashReporter?.LogLevelFinish(level);
		}

		public override void LogException(Exception exception)
		{
			_crashReporter?.LogException(exception);
		}

		public override void SetCustomData(string key, string value)
		{
			if (string.IsNullOrEmpty(key))
			{
				VoodooLog.LogDebug(Module.COMMON, "CrashReportManager", "Can not send a null or empty key on a custom data");
			}
			else if (string.IsNullOrEmpty(value))
			{
				VoodooLog.LogDebug(Module.COMMON, "CrashReportManager", "Can not send a null or empty value as a custom data (key: '" + key + "')");
			}
			else
			{
				_crashReporter?.SetCustomData(key, value);
			}
		}

		public override void Log(string message)
		{
			_crashReporter?.Log(message);
		}

		public override void LogAdEvent(string eventName, AdEventParams adEventParams)
		{
			_crashReporter?.LogAdEvent(eventName, adEventParams);
		}

		public override void SetUserId(string userId)
		{
			_crashReporter?.SetUserId(userId);
		}

		public override void SetUserProfile(string profile)
		{
			_crashReporter?.SetUserProfile(profile);
		}

		public override float GetUserPercentage(CrashReporter crashReporter)
		{
			if (!_crashReporterPercentages.ContainsKey(crashReporter))
			{
				return 0f;
			}
			return _crashReporterPercentages[crashReporter];
		}

		private static void RemoveOutdatedSavedConfigurations()
		{
			if (NintendoPlayerPrefs.HasKey("PLAYER_PREF_CRASHLYTICSVoodoo.Sauce.CrashReport.CrashReporter"))
			{
				NintendoPlayerPrefs.DeleteKey("PLAYER_PREF_CRASHLYTICSVoodoo.Sauce.CrashReport.CrashReporter");
			}
		}

		private ICrashlyticsProvider SelectCrashReporter()
		{
			if (PlatformUtils.UNITY_EDITOR)
			{
				VoodooLog.LogDebug(Module.ANALYTICS, "CrashReportManager", "No crash reporter is initialized in the Editor Mode");
				return null;
			}
			Dictionary<CrashReporter, ICrashlyticsProvider> dictionary = new Dictionary<CrashReporter, ICrashlyticsProvider>();
			List<CrashReporterProviderBucket> list = new List<CrashReporterProviderBucket>();
			List<ICrashlyticsProvider> list2 = new List<ICrashlyticsProvider>();
			double num = 0.0;
			foreach (Type type in AssembliesUtils.GetTypes(typeof(ICrashlyticsProvider)))
			{
				ICrashlyticsProvider crashlyticsProvider = (ICrashlyticsProvider)Activator.CreateInstance(type);
				crashlyticsProvider.Configure(_voodooSettings);
				CrashReporter key = crashlyticsProvider.CrashReporterType();
				float num2 = crashlyticsProvider.UserPercentage();
				if ((double)num2 == 0.0)
				{
					VoodooLog.LogDebug(Module.ANALYTICS, "CrashReportManager", $"The crash reporter '{key.ToString()}' is disabled (because percentage == {num2})");
					continue;
				}
				if (dictionary.ContainsKey(key))
				{
					VoodooLog.LogWarning(Module.ANALYTICS, "CrashReportManager", "More than one crash reporter '" + key.ToString() + "' is defined, only one is kept");
					continue;
				}
				VoodooLog.LogDebug(Module.ANALYTICS, "CrashReportManager", "Crash reporter '" + key.ToString() + "' configured");
				dictionary[key] = crashlyticsProvider;
				if ((double)num2 < 0.0)
				{
					list2.Add(crashlyticsProvider);
					continue;
				}
				num += (double)num2;
				list.Add(new CrashReporterProviderBucket(num, crashlyticsProvider));
				_crashReporterPercentages.Add(crashlyticsProvider.CrashReporterType(), num2);
			}
			if (num > 100.0)
			{
				VoodooLog.LogWarning(Module.ANALYTICS, "CrashReportManager", "The cumulative percentage of all the crash reporters exceeds 100%, please fix it in the VS settings or in VoodooTune");
			}
			else if (list2.Count > 0)
			{
				double num3 = (100.0 - num) / (double)list2.Count;
				foreach (ICrashlyticsProvider item in list2)
				{
					num += num3;
					list.Add(new CrashReporterProviderBucket(num, item));
					_crashReporterPercentages.Add(item.CrashReporterType(), (float)num3);
				}
			}
			if (NintendoPlayerPrefs.HasKey("PLAYER_PREF_CRASHLYTICSVoodoo.Sauce.CrashReport.CrashReporter.v2"))
			{
				string @string = NintendoPlayerPrefs.GetString("PLAYER_PREF_CRASHLYTICSVoodoo.Sauce.CrashReport.CrashReporter.v2");
				if (!Enum.TryParse<CrashReporter>(@string, out var result))
				{
					VoodooLog.LogWarning(Module.ANALYTICS, "CrashReportManager", "Used a crash reporter that is not used anymore '" + @string + "'");
					NintendoPlayerPrefs.DeleteKey("PLAYER_PREF_CRASHLYTICSVoodoo.Sauce.CrashReport.CrashReporter.v2");
				}
				else
				{
					if (dictionary.ContainsKey(result))
					{
						VoodooLog.LogDebug(Module.ANALYTICS, "CrashReportManager", "Crash reporter used: '" + @string + "' (from cache)");
						return dictionary[result];
					}
					VoodooLog.LogWarning(Module.ANALYTICS, "CrashReportManager", "The crash reporter '" + @string + "' should be used but it is not configured (is it disabled?)");
				}
			}
			float num4 = UnityEngine.Random.Range(0f, (float)num);
			foreach (CrashReporterProviderBucket item2 in list)
			{
				if (!(item2.Percentage < (double)num4))
				{
					ICrashlyticsProvider crashReporterProvider = item2.CrashReporterProvider;
					NintendoPlayerPrefs.SetString("PLAYER_PREF_CRASHLYTICSVoodoo.Sauce.CrashReport.CrashReporter.v2", crashReporterProvider.CrashReporterType().ToString());
					VoodooLog.LogDebug(Module.ANALYTICS, "CrashReportManager", "Crash reporter used: '" + crashReporterProvider.CrashReporterType().ToString() + "' (randomly picked up)");
					return crashReporterProvider;
				}
			}
			VoodooLog.LogWarning(Module.ANALYTICS, "CrashReportManager", "No crash reporter loaded");
			return null;
		}
	}
}
